home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / MultiSession 1.04 Source / Core 27⁄June⁄1993 / CWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-27  |  27.4 KB  |  1,134 lines  |  [TEXT/KAHL]

  1. /* CWindow.c */
  2.  
  3. #define COMPILING_CWINDOW_C
  4. #include "CWindow.h"
  5. #include "Memory.h"
  6. #include "CSack.h"
  7. #include "CApplication.h"
  8. #include "Compatibility.h"
  9. #include "MenuController.h"
  10.  
  11.  
  12. CWindow*                    ActiveWindow;
  13.  
  14. LongPoint                    ZeroPoint = {0,0};
  15.  
  16. #define MAXTEXTSIZING (32767)
  17.  
  18. #define DEBUGSCROLL(Rgn)  InvertRgn(Rgn); { long Start; Start = TickCount(); while ((signed long)TickCount() - Start < 4); } InvertRgn(Rgn);
  19.  
  20.  
  21. EXECUTE(static char GrafErrMsg[]
  22.     = {"CWindow drawing function called while other window's GrafPort was active."};)
  23.  
  24.  
  25. /* */        CWindow::CWindow()
  26.     {
  27.         CSack*        Temp;
  28.  
  29.         OurKeyReceiver = NIL;
  30.         Temp = new CSack;
  31.         Temp->ISack(sizeof(CViewRect*),128);
  32.         ListOfWindowClients = Temp;
  33.         MyGrafPtr = NIL;
  34.         ZoomStatePartCode = inZoomOut; /* we start zoomed in */
  35.     }
  36.  
  37.  
  38. /* */        CWindow::~CWindow()
  39.     {
  40.         CViewRect*    Thang;
  41.  
  42.         ERROR(Initialized != True,PRERR(ForceAbort,
  43.             "CWindow::~CWindow called on uninitialized object."));
  44.         ListOfWindowClients->ResetScan();
  45.         while (ListOfWindowClients->GetNext(&Thang))
  46.             {
  47.                 Thang->Window = NIL;
  48.             }
  49.         delete ListOfWindowClients;
  50.         if (ActiveWindow == this)
  51.             {
  52.                 ActiveWindow = NIL;
  53.             }
  54.         DeleteMyGrafPtr();
  55.     }
  56.  
  57.  
  58. /* this creates the window record.  Override & call this last */
  59. void        CWindow::IWindow(LongPoint Start, LongPoint Extent, MyBoolean ModalFlag,
  60.                     MyBoolean GrowFlag, MyBoolean ZoomFlag)
  61.     {
  62.         Rect        ShortWhere;
  63.  
  64.         ERROR(Initialized == True,PRERR(ForceAbort,
  65.             "CWindow::IWindow called on already initialized object."));
  66.         EXECUTE(Initialized = True);
  67.         Modality = ModalFlag;
  68.         Growable = GrowFlag;
  69.         Zoomable = ZoomFlag;
  70.         Origin = ZeroPoint; /* this never changes, since the window is what everyone */
  71.         /* else references their origins from. */
  72.         MakeMyGrafPtr(Start,Extent);
  73.         IEnclosure(Start,Extent,this,NIL);
  74.         DoFindPosition();
  75.         VisRectStart = ZeroPoint;
  76.         VisRectExtent = Extent;
  77.         Origin = ZeroPoint;
  78.         SetWRefCon(MyGrafPtr,(long)this);
  79.     }
  80.  
  81.  
  82. /* user should override this & create his own MyWindowPtr */
  83. void        CWindow::MakeMyGrafPtr(LongPoint Start, LongPoint Extent)
  84.     {
  85.         Rect        BoundsRect;
  86.         short        WindowCode;
  87.  
  88.         ERROR(Initialized != True,PRERR(ForceAbort,
  89.             "CWindow::MakeMyGrafPtr called on uninitialized object."));
  90.         ERROR(MyGrafPtr!=NIL,PRERR(ForceAbort,
  91.             "CWindow::MakeMyGrafPtr called, but MyGrafPtr is not NIL."));
  92.         BoundsRect = RectOf(Start.x,Start.y,Start.x+Extent.x,Start.y+Extent.y);
  93.         if (Growable)
  94.             {
  95.                 if (Zoomable)
  96.                     {
  97.                         WindowCode = zoomDocProc;
  98.                     }
  99.                  else
  100.                     {
  101.                         WindowCode = documentProc;
  102.                     }
  103.             }
  104.          else
  105.             {
  106.                 if (Zoomable)
  107.                     {
  108.                         WindowCode = zoomNoGrow;
  109.                     }
  110.                  else
  111.                     {
  112.                         WindowCode = noGrowDocProc;
  113.                     }
  114.             }
  115.         MyGrafPtr = NewWindow(NIL,&BoundsRect,"\p",True,WindowCode,(void*)-1,
  116.             True,(long)this);
  117.         if (MyGrafPtr == NIL)
  118.             {
  119.                 PRERR(ForceAbort,"NewWindow failed to allocate memory.");
  120.             }
  121.     }
  122.  
  123.  
  124. void            CWindow::DeleteMyGrafPtr(void)
  125.     {
  126.         ERROR(MyGrafPtr==NIL,PRERR(ForceAbort,
  127.             "CWindow::DeleteMyGrafPtr called but MyGrafPtr is already NIL."));
  128.         DisposeWindow(MyGrafPtr);
  129.     }
  130.  
  131.  
  132. void            CWindow::DoUpdate(void)
  133.     {
  134.         ERROR(Initialized != True,PRERR(ForceAbort,
  135.             "CWindow::DoUpdate called on uninitialized object."));
  136.         ERROR(MyGrafPtr==NIL,PRERR(ForceAbort,
  137.             "CWindow::DoUpdate called but MyGrafPtr is already NIL."));
  138.         BeginUpdate(MyGrafPtr);  /* begin the process */
  139.         inherited::DoUpdate();
  140.         if (Growable)
  141.             {
  142.                 LongPoint            LocalExtent = {16,16};
  143.  
  144.                 SetUpPort();
  145.                 if (Suspended)
  146.                     {
  147.                         LDrawPicture(GetPic(EmptyGrowIconPictID),
  148.                             LongPointOf(Extent.x-15,Extent.y-15),LocalExtent);
  149.                     }
  150.                  else
  151.                     {
  152.                         LDrawPicture(GetPic(GrowIconPictID),
  153.                             LongPointOf(Extent.x-15,Extent.y-15),LocalExtent);
  154.                     }
  155.             }
  156.         EndUpdate(MyGrafPtr);  /* stop updating */
  157.     }
  158.  
  159.  
  160. void            CWindow::DoSuspend(void)
  161.     {
  162.         ERROR(Initialized != True,PRERR(ForceAbort,
  163.             "CWindow::DoSuspend called on uninitialized object."));
  164.         OurKeyReceiver = KeyReceiverViewRect;
  165.         if (KeyReceiverViewRect != NIL)
  166.             {
  167.                 KeyReceiverViewRect->RelinquishKeyReceivership();
  168.             }
  169.         if (Growable)
  170.             {
  171.                 LongPoint            LocalExtent = {16,16};
  172.  
  173.                 SetUpPort();
  174.                 LDrawPicture(GetPic(EmptyGrowIconPictID),
  175.                     LongPointOf(Extent.x-15,Extent.y-15),LocalExtent);
  176.             }
  177.         inherited::DoSuspend();
  178.         KeyReceiverViewRect = NIL;
  179.     }
  180.  
  181.  
  182. void            CWindow::DoResume(void)
  183.     {
  184.         ERROR(Initialized != True,PRERR(ForceAbort,
  185.             "CWindow::DoResume called on uninitialized object."));
  186.         if (Growable)
  187.             {
  188.                 LongPoint            LocalExtent = {16,16};
  189.  
  190.                 SetUpPort();
  191.                 LDrawPicture(GetPic(GrowIconPictID),
  192.                     LongPointOf(Extent.x-15,Extent.y-15),LocalExtent);
  193.             }
  194.         inherited::DoResume();
  195.         if (OurKeyReceiver != NIL)
  196.             {
  197.                 OurKeyReceiver->BecomeKeyReceiver();
  198.             }
  199.     }
  200.  
  201.  
  202. void            CWindow::SetDefaultKeyReceiver(CViewRect* TheReceiver)
  203.     {
  204.         ERROR(Initialized != True,PRERR(ForceAbort,
  205.             "CWindow::SetDefaultKeyReceiver called on uninitialized object."));
  206.         ERROR(!Suspended,PRERR(ForceAbort,
  207.             "CWindow::SetDefaultKeyReceiver attempted to set default key Receiver while not suspended."));
  208.         OurKeyReceiver = TheReceiver;
  209.     }
  210.  
  211.  
  212. /* track the go-away thing */
  213. void            CWindow::DoGoAway(Point GlobalStart)
  214.     {
  215.         ERROR(Initialized != True,PRERR(ForceAbort,
  216.             "CWindow::DoGoAway called on uninitialized object."));
  217.         ERROR(MyGrafPtr==NIL,PRERR(ForceAbort,
  218.             "CWindow::DoGoAway called but MyGrafPtr is already NIL."));
  219.         if (TrackGoAway(MyGrafPtr,GlobalStart))
  220.             {
  221.                 GoAway();
  222.             }
  223.     }
  224.  
  225.  
  226. /* override to provide a go-away check function */
  227. void            CWindow::GoAway(void)
  228.     {
  229.         ERROR(Initialized != True,PRERR(ForceAbort,
  230.             "CWindow::GoAway called on uninitialized object."));
  231.         DoMenuCommand(mFileClose);
  232.     }
  233.  
  234.  
  235. /* get the size constraints for the window */
  236. Rect        CWindow::GetConstraint(void)
  237.     {
  238.         Rect        Temp = {100,100,32767,32767};
  239.  
  240.         ERROR(Initialized != True,PRERR(ForceAbort,
  241.             "CWindow::GetConstraint called on uninitialized object."));
  242.         return Temp;
  243.     }
  244.  
  245.  
  246. LongPoint    CWindow::SnapToGrid(LongPoint NewWindowSize)
  247.     {
  248.         return NewWindowSize;
  249.     }
  250.  
  251.  
  252. void            CWindow::DoFindPosition(void)
  253.     {
  254.         Point        Delta = {0,0};
  255.  
  256.         ERROR(Initialized != True,PRERR(ForceAbort,
  257.             "CWindow::DoFindPosition called on uninitialized object."));
  258.         SetMyPort();
  259.         LocalToGlobal(&Delta); /* find top-left with respect to screen */
  260.         Start.x = Delta.h;
  261.         Start.y = Delta.v;
  262.     }
  263.  
  264.  
  265. void            CWindow::SetNewSize(LongPoint NewWindowSize)
  266.     {
  267.         LongPoint        DeltaExtent;
  268.         CViewRect*    Thang;
  269.  
  270.         ERROR(Initialized != True,PRERR(ForceAbort,
  271.             "CWindow::SetNewSize called on uninitialized object."));
  272.         DeltaExtent.x = NewWindowSize.x - Extent.x;
  273.         DeltaExtent.y = NewWindowSize.y - Extent.y;
  274.         Extent = NewWindowSize;
  275.         SizeWindow(MyGrafPtr,Extent.x,Extent.y,True);
  276.         DoFindPosition();
  277.         VisRectStart = ZeroPoint;
  278.         VisRectExtent = Extent;
  279.         Origin = ZeroPoint;
  280.         SetUpPort();
  281.         Window->LEraseRect(ZeroPoint,Extent);
  282.         Window->InvalidateLong(ZeroPoint,Extent);
  283.         ListOfObjects->ResetScan();
  284.         while (ListOfObjects->GetNext(&Thang))
  285.             {
  286.                 Thang->DoEnclosureResized(DeltaExtent);
  287.             }
  288.     }
  289.  
  290.  
  291. void            CWindow::DoGrow(Point GlobalStart)
  292.     {
  293.         long                Result;
  294.         Rect                Limits;
  295.  
  296.         ERROR(Initialized != True,PRERR(ForceAbort,
  297.             "CWindow::DoGrow called on uninitialized object."));
  298.         Limits = GetConstraint();
  299.         Result = GrowWindow(MyGrafPtr,GlobalStart,&Limits);
  300.         if (Result != 0)
  301.             {
  302.                 SetNewSize(SnapToGrid(LongPointOf(0x0000ffff & Result/*X coord*/,
  303.                     0x0000ffff & (Result >> 16)/*Ycoord*/)));
  304.             }
  305.     }
  306.  
  307.  
  308. void            CWindow::DoZoomIn(Point GlobalStart)
  309.     {
  310.         if (TrackBox(MyGrafPtr,GlobalStart,inZoomIn))
  311.             {
  312.                 ZoomIn();
  313.             }
  314.     }
  315.  
  316.  
  317. void            CWindow::DoZoomOut(Point GlobalStart)
  318.     {
  319.         if (TrackBox(MyGrafPtr,GlobalStart,inZoomOut))
  320.             {
  321.                 ZoomOut();
  322.             }
  323.     }
  324.  
  325.  
  326. void            CWindow::ZoomIn(void)
  327.     {
  328.         ZoomStatePartCode = inZoomOut; /* opposite--state BEFORE THIS zoom occurs */
  329.         SetUpPort();
  330.         LEraseRect(ZeroPoint,Extent);
  331.         InvalidateLong(ZeroPoint,Extent);
  332.         ZoomWindow(MyGrafPtr,inZoomIn,False);
  333.         SetNewSize(SnapToGrid(
  334.             LongPointOf(MyGrafPtr->portRect.right - MyGrafPtr->portRect.left,
  335.             MyGrafPtr->portRect.bottom - MyGrafPtr->portRect.top)));
  336.     }
  337.  
  338.  
  339. void            CWindow::ZoomOut(void)
  340.     {
  341.         ZoomStatePartCode = inZoomIn; /* opposite--state BEFORE THIS zoom occurs */
  342.         SetUpPort();
  343.         LEraseRect(ZeroPoint,Extent);
  344.         InvalidateLong(ZeroPoint,Extent);
  345.         ZoomWindow(MyGrafPtr,inZoomOut,False);
  346.         SetNewSize(SnapToGrid(
  347.             LongPointOf(MyGrafPtr->portRect.right - MyGrafPtr->portRect.left,
  348.             MyGrafPtr->portRect.bottom - MyGrafPtr->portRect.top)));
  349.     }
  350.  
  351.  
  352. void            CWindow::DoDrag(Point GlobalStart)
  353.     {
  354.         Rect                BoundsRect;
  355.         RgnHandle        BoundsRegion;
  356.  
  357.         ERROR(Initialized != True,PRERR(ForceAbort,
  358.             "CWindow::DoDrag called on uninitialized object."));
  359.         BoundsRegion = GetGrayRgn();
  360.         BoundsRect = (**BoundsRegion).rgnBBox;
  361.         InsetRect(&BoundsRect,4,4);
  362.         DragWindow(MyGrafPtr,GlobalStart,&BoundsRect);
  363.         DoFindPosition();
  364.     }
  365.  
  366.  
  367. void            CWindow::DoMouseDown(MyEventRec Event)
  368.     {
  369.         ERROR(Initialized != True,PRERR(ForceAbort,
  370.             "CWindow::DoMouseDown called on uninitialized object."));
  371.         if (ActiveWindow == this)
  372.             {
  373.                 inherited::DoMouseDown(Event);
  374.             }
  375.          else
  376.             {
  377.                 SelectWindow(MyGrafPtr);
  378.             }
  379.     }
  380.  
  381.  
  382. void            CWindow::BecomeActiveWindow(void)
  383.     {
  384.         ERROR(Initialized != True,PRERR(ForceAbort,
  385.             "CWindow::BecomeActiveWindow called on uninitialized object."));
  386.         if ((ActiveWindow == NIL) || ((ActiveWindow != NIL)
  387.             && (ActiveWindow->Modality == ModelessWindow)))
  388.             {
  389.                 SelectWindow(MyGrafPtr);
  390.             }
  391.     }
  392.  
  393.  
  394. void            CWindow::RegisterClient(CViewRect* Client)
  395.     {
  396.         ERROR(Initialized != True,PRERR(ForceAbort,
  397.             "CWindow::RegisterClient called on uninitialized object."));
  398.         ListOfWindowClients->PushElement(&Client);
  399.     }
  400.  
  401.  
  402. void            CWindow::DeregisterClient(CViewRect* Client)
  403.     {
  404.         ERROR(Initialized != True,PRERR(ForceAbort,
  405.             "CWindow::DeregisterClient called on uninitialized object."));
  406.         ListOfWindowClients->KillElement(&Client);
  407.     }
  408.  
  409.  
  410. /********************************************************************************/
  411. /* LongRect versions of QuickDraw routines */
  412.  
  413.  
  414. void            CWindow::SetMyPort(void)
  415.     {
  416.         Rect            Temp;
  417.  
  418.         if (thePort != MyGrafPtr)
  419.             {
  420.                 SetPort(MyGrafPtr);
  421.             }
  422.         ClipStart = ZeroPoint;
  423.         ClipExtent = Extent;
  424.         ResetPen();
  425.         EXECUTE(SetText(systemFont,outline,srcOr,36,0));
  426.     }
  427.  
  428.  
  429. void            CWindow::SetOrigin(LongPoint TheOrigin)
  430.     {
  431.         DrawingOrigin = TheOrigin;
  432.     }
  433.  
  434.  
  435. void            CWindow::SetClipRect(LongPoint Start, LongPoint Extent)
  436.     {
  437.         Rect                Temp;
  438.  
  439.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  440.         Start.x += DrawingOrigin.x;
  441.         Start.y += DrawingOrigin.y;
  442.         SectLongRect(ClipStart,ClipExtent,Start,Extent,&ClipStart,&ClipExtent);
  443.         Temp.left = ClipStart.x;
  444.         Temp.top = ClipStart.y;
  445.         Temp.right = ClipStart.x + ClipExtent.x;
  446.         Temp.bottom = ClipStart.y + ClipExtent.y;
  447.         ClipRect(&Temp);
  448.     }
  449.  
  450.  
  451. void            CWindow::SetPen(short Width, short Height, short Mode, Pattern ThePattern)
  452.     {
  453.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  454.         PenSize(Width,Height);
  455.         PenMode(Mode);
  456.         PenPat(ThePattern);
  457.     }
  458.  
  459.  
  460. void            CWindow::ResetPen(void)
  461.     {
  462.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  463.         PenNormal();
  464.     }
  465.  
  466.  
  467. void            CWindow::SetPenMode(short Mode)
  468.     {
  469.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  470.         PenMode(Mode);
  471.     }
  472.  
  473.  
  474. void            CWindow::SetPenSize(short Width, short Height)
  475.     {
  476.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  477.         PenSize(Width,Height);
  478.     }
  479.  
  480.  
  481. void            CWindow::SetGreyishTextOr(void)
  482.     {
  483.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  484.         ResetPen();
  485.         PenMode(srcCopy);
  486.         PenPat(gray);
  487.         TextMode(grayishTextOr);
  488.     }
  489.  
  490.  
  491. void            CWindow::DrawLine(LongPoint Start, LongPoint Extent)
  492.     {
  493.         Rect        Place;
  494.  
  495.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  496.         if (LongRectToShort(Start,Extent,&Place))
  497.             {
  498.                 MoveTo(Place.left,Place.top);
  499.                 LineTo(Place.right,Place.bottom);
  500.             }
  501.     }
  502.  
  503.  
  504. void            CWindow::SetText(short FontID, Style Face, short Mode, short PointSize, Fixed Space)
  505.     {
  506.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  507.         TextFont(FontID);
  508.         TextFace(Face);
  509.         TextMode(Mode);
  510.         TextSize(PointSize);
  511.         SpaceExtra(Space);
  512.     }
  513.  
  514.  
  515. void            CWindow::SetTextMode(short Mode)
  516.     {
  517.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  518.         TextMode(Mode);
  519.     }
  520.  
  521.  
  522. void            CWindow::LTextBox(LongPoint Start, LongPoint Extent, Handle Text, short Justification)
  523.     {
  524.         Rect        Temp;
  525.  
  526.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  527.         LongRectToShort(Start,Extent,&Temp);
  528.         HLock(Text);
  529.         TextBox(*Text,HandleSize(Text),&Temp,(short)Justification);
  530.         HUnlock(Text);
  531.     }
  532.  
  533.  
  534. void            CWindow::LDrawText(LongPoint Start, LongPoint Extent, Handle Text, short Justification)
  535.     {
  536.         Rect            Temp;
  537.         short            NumPixels;
  538.         short            YPos;
  539.         FontInfo    FInfo;
  540.  
  541.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  542.         LongRectToShort(Start,Extent,&Temp);
  543.         GetFontInfo(&FInfo);
  544.         HLock(Text);
  545.         NumPixels = TextWidth(*Text,0,HandleSize(Text));
  546.         YPos = (Temp.top+Temp.bottom-(FInfo.ascent+FInfo.descent+FInfo.leading))/2
  547.             + FInfo.ascent + FInfo.leading;
  548.         switch (Justification)
  549.             {
  550.                 case JustifyLeft:
  551.                     MoveTo(Temp.left,YPos);
  552.                     break;
  553.                 case JustifyCenter:
  554.                     MoveTo((Temp.left+Temp.right-NumPixels)/2,YPos);
  555.                     break;
  556.                 case JustifyRight:
  557.                     MoveTo((Temp.right-NumPixels),YPos);
  558.                     break;
  559.                 default:
  560.                     EXECUTE(PRERR(AllowResume,
  561.                         "Illegal text justification code passed to CWindow::LDrawText."));
  562.                     break;
  563.             }
  564.         DrawText(*Text,0,HandleSize(Text));
  565.         HUnlock(Text);
  566.     }
  567.  
  568.  
  569. void            CWindow::LDrawTextPtr(LongPoint Start, LongPoint Extent, char* Text,
  570.                         long Length, short Justification)
  571.     {
  572.         Rect            Temp;
  573.         short            NumPixels;
  574.         short            YPos;
  575.         FontInfo    FInfo;
  576.  
  577.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  578.         LongRectToShort(Start,Extent,&Temp);
  579.         GetFontInfo(&FInfo);
  580.         NumPixels = TextWidth(Text,0,Length);
  581.         YPos = (Temp.top+Temp.bottom-(FInfo.ascent+FInfo.descent+FInfo.leading))/2
  582.             + FInfo.ascent + FInfo.leading;
  583.         switch (Justification)
  584.             {
  585.                 case JustifyLeft:
  586.                     MoveTo(Temp.left,YPos);
  587.                     break;
  588.                 case JustifyCenter:
  589.                     MoveTo((Temp.left+Temp.right-NumPixels)/2,YPos);
  590.                     break;
  591.                 case JustifyRight:
  592.                     MoveTo((Temp.right-NumPixels),YPos);
  593.                     break;
  594.                 default:
  595.                     EXECUTE(PRERR(AllowResume,
  596.                         "Illegal text justification code passed to CWindow::LDrawText."));
  597.                     break;
  598.             }
  599.         DrawText(Text,0,Length);
  600.     }
  601.  
  602.  
  603. long            CWindow::LMeasureText(char* Text, long NumChars)
  604.     {
  605.         long            CurrentLinePixels;
  606.         long            IndexIntoBuffer;
  607.  
  608.         CurrentLinePixels = 0;
  609.         IndexIntoBuffer = 0;
  610.         while (NumChars > 0)
  611.             {
  612.                 if (NumChars > MAXTEXTSIZING)
  613.                     {
  614.                         CurrentLinePixels += TextWidth(&(Text[IndexIntoBuffer]),0,MAXTEXTSIZING);
  615.                         NumChars -= MAXTEXTSIZING;
  616.                         IndexIntoBuffer += MAXTEXTSIZING;
  617.                     }
  618.                  else
  619.                     {
  620.                         CurrentLinePixels += TextWidth(&(Text[IndexIntoBuffer]),0,NumChars);
  621.                         NumChars = 0;
  622.                     }
  623.             }
  624.         return CurrentLinePixels;
  625.     }
  626.  
  627.  
  628. void            CWindow::LDrawPicture(PicHandle ThePicture, LongPoint Start, LongPoint Extent)
  629.     {
  630.         Rect        Temp;
  631.  
  632.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  633.         if (LongRectToShort(Start,Extent,&Temp))
  634.             {
  635.                 DrawPicture(ThePicture,&Temp);
  636.             }
  637.     }
  638.  
  639.  
  640. void            CWindow::LFrameRect(LongPoint Start, LongPoint Extent)
  641.     {
  642.         Rect        Temp;
  643.  
  644.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  645.         LongRectToShort(Start,Extent,&Temp);
  646.         FrameRect(&Temp);
  647.     }
  648.  
  649.  
  650. void            CWindow::LPaintRect(LongPoint Start, LongPoint Extent)
  651.     {
  652.         Rect        Temp;
  653.  
  654.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  655.         LongRectToShort(Start,Extent,&Temp);
  656.         PaintRect(&Temp);
  657.     }
  658.  
  659.  
  660. void            CWindow::LEraseRect(LongPoint Start, LongPoint Extent)
  661.     {
  662.         Rect        Temp;
  663.  
  664.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  665.         LongRectToShort(Start,Extent,&Temp);
  666.         EraseRect(&Temp);
  667.     }
  668.  
  669.  
  670. void            CWindow::LFrameOval(LongPoint Start, LongPoint Extent)
  671.     {
  672.         Rect        Temp;
  673.  
  674.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  675.         LongRectToShort(Start,Extent,&Temp);
  676.         FrameOval(&Temp);
  677.     }
  678.  
  679.  
  680. void            CWindow::LPaintOval(LongPoint Start, LongPoint Extent)
  681.     {
  682.         Rect        Temp;
  683.  
  684.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  685.         LongRectToShort(Start,Extent,&Temp);
  686.         PaintOval(&Temp);
  687.     }
  688.  
  689.  
  690. void            CWindow::LEraseOval(LongPoint Start, LongPoint Extent)
  691.     {
  692.         Rect        Temp;
  693.  
  694.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  695.         LongRectToShort(Start,Extent,&Temp);
  696.         EraseOval(&Temp);
  697.     }
  698.  
  699.  
  700. void            CWindow::LFrameRoundRect(LongPoint Start, LongPoint Extent, short OvalWidth, short OvalHeight)
  701.     {
  702.         Rect        Temp;
  703.  
  704.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  705.         LongRectToShort(Start,Extent,&Temp);
  706.         FrameRoundRect(&Temp,OvalWidth,OvalHeight);
  707.     }
  708.  
  709.  
  710. void            CWindow::LPaintRoundRect(LongPoint Start, LongPoint Extent, short OvalWidth, short OvalHeight)
  711.     {
  712.         Rect        Temp;
  713.  
  714.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  715.         LongRectToShort(Start,Extent,&Temp);
  716.         PaintRoundRect(&Temp,OvalWidth,OvalHeight);
  717.     }
  718.  
  719.  
  720. void            CWindow::LEraseRoundRect(LongPoint Start, LongPoint Extent, short OvalWidth, short OvalHeight)
  721.     {
  722.         Rect        Temp;
  723.  
  724.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  725.         LongRectToShort(Start,Extent,&Temp);
  726.         EraseRoundRect(&Temp,OvalWidth,OvalHeight);
  727.     }
  728.  
  729.  
  730. void            CWindow::SetPattern(Pattern ThePattern)
  731.     {
  732.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  733.         PenPat(ThePattern);
  734.     }
  735.  
  736.  
  737. void            CWindow::InvalidateLong(LongPoint Start, LongPoint Extent)
  738.     {
  739.         Rect            ShortOne;
  740.  
  741.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  742.         LongRectToShort(Start,Extent,&ShortOne);
  743.         Start.x = ShortOne.left;
  744.         Start.y = ShortOne.top;
  745.         Extent.x = ShortOne.right - ShortOne.left;
  746.         Extent.y = ShortOne.bottom - ShortOne.top;
  747.         SectLongRect(Start,Extent,ClipStart,ClipExtent,&Start,&Extent);
  748.         ShortOne.left = Start.x;
  749.         ShortOne.top = Start.y;
  750.         ShortOne.right = Start.x + Extent.x;
  751.         ShortOne.bottom = Start.y + Extent.y;
  752.         InvalRect(&ShortOne);
  753.     }
  754.  
  755.  
  756. void            CWindow::ScrollLong(LongPoint Start, LongPoint Extent, LongPoint Change)
  757.     {
  758.         RgnHandle        UpdateRegion;
  759.         RgnHandle        WhiteRegion;
  760.         Rect                TheRect;
  761.         RgnHandle        InvalidRegion;
  762.         RgnHandle        TempRgn;
  763.  
  764.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  765.         /* we constrain the range into a short integer.  This will not cause */
  766.         /* problems until we start getting REALLY BIG monitors. */
  767.         if ((Change.x < -32767) || (Change.x > 32767) || (Change.y < -32767)
  768.             || (Change.y > 32767))
  769.             {
  770.                 /* erase screen and invalidate nothing */
  771.                 LEraseRect(Start,Extent);
  772.                 return;
  773.             }
  774.         /* converting to a regular rect */
  775.         LongRectToShort(Start,Extent,&TheRect);
  776.         /* create update region */
  777.         UpdateRegion = NewRgn();
  778.         /* do the scroll */
  779.         ScrollRect(&TheRect,Change.x,Change.y,UpdateRegion);
  780.         /* we want to add to the update region any area that was already invalid */
  781.         InvalidRegion = NewRgn();
  782.         TempRgn = NewRgn();
  783.         RectRgn(InvalidRegion,&TheRect);
  784.         CopyRgn(InvalidRegion,TempRgn);
  785.         SectRgn(((WindowPeek)MyGrafPtr)->updateRgn,InvalidRegion,InvalidRegion);
  786.         OffsetRgn(InvalidRegion,Change.x,Change.y);
  787.         SectRgn(InvalidRegion,TempRgn,InvalidRegion);
  788.         DisposeRgn(TempRgn);
  789.         UnionRgn(InvalidRegion,UpdateRegion,UpdateRegion);
  790.         DisposeRgn(InvalidRegion);
  791.         /* it is assumed that the program will redraw the empty area created by scrolling. */
  792.         /* we only want to add the area created by overlapping windows. */
  793.         WhiteRegion = NewRgn();
  794.         if (Change.x >= 0)
  795.             {
  796.                 SetRectRgn(WhiteRegion,TheRect.left,TheRect.top,
  797.                     TheRect.left + Change.x,TheRect.bottom);
  798.             }
  799.          else
  800.             {
  801.                 SetRectRgn(WhiteRegion,TheRect.right + Change.x,
  802.                     TheRect.top,TheRect.right,TheRect.bottom);
  803.             }
  804.         DiffRgn(UpdateRegion,WhiteRegion,UpdateRegion);
  805.         if (Change.y >= 0)
  806.             {
  807.                 SetRectRgn(WhiteRegion,TheRect.left,TheRect.top,
  808.                     TheRect.right,TheRect.top + Change.y);
  809.             }
  810.          else
  811.             {
  812.                 SetRectRgn(WhiteRegion,TheRect.left,TheRect.bottom + Change.y,
  813.                     TheRect.right,TheRect.bottom);
  814.             }
  815.         DiffRgn(UpdateRegion,WhiteRegion,UpdateRegion);
  816. /* I have to do this since InvalRgn isn't working properly. */
  817. UnionRgn(UpdateRegion,((WindowPeek)MyGrafPtr)->updateRgn,((WindowPeek)MyGrafPtr)->updateRgn);
  818.         InvalRgn(UpdateRegion);
  819.         /* get rid of update region */
  820.         DisposeRgn(UpdateRegion);
  821.         DisposeRgn(WhiteRegion);
  822.     }
  823.  
  824.  
  825. void            CWindow::ScrollLongAndInvalidate(LongPoint Start, LongPoint Extent, LongPoint Change)
  826.     {
  827.         RgnHandle        UpdateRegion;
  828.         Rect                TheRect;
  829.         RgnHandle        InvalidRegion;
  830.         RgnHandle        TempRgn;
  831.  
  832.         ERROR(MyGrafPtr != thePort,PRERR(ForceAbort,GrafErrMsg));
  833.         if ((Change.x < -32767) || (Change.x > 32767) || (Change.y < -32767)
  834.             || (Change.y > 32767))
  835.             {
  836.                 /* if we scroll out of qd space, just erase & return */
  837.                 LEraseRect(Start,Extent);
  838.                 return;
  839.             }
  840.         /* converting to a regular rect */
  841.         LongRectToShort(Start,Extent,&TheRect);
  842.         /* create update region */
  843.         UpdateRegion = NewRgn();
  844.         /* do the scroll */
  845.         ScrollRect(&TheRect,Change.x,Change.y,UpdateRegion);
  846.         /* we want to add to the update region any area that was already invalid */
  847.         InvalidRegion = NewRgn();
  848.         TempRgn = NewRgn();
  849.         RectRgn(InvalidRegion,&TheRect);
  850.         CopyRgn(InvalidRegion,TempRgn);
  851.         SectRgn(((WindowPeek)MyGrafPtr)->updateRgn,InvalidRegion,InvalidRegion);
  852.         OffsetRgn(InvalidRegion,Change.x,Change.y);
  853.         SectRgn(InvalidRegion,TempRgn,InvalidRegion);
  854.         DisposeRgn(TempRgn);
  855.         UnionRgn(InvalidRegion,UpdateRegion,UpdateRegion);
  856.         DisposeRgn(InvalidRegion);
  857.         /* invalidate all bad areas */
  858. /* I have to do this since InvalRgn isn't working properly. */
  859. UnionRgn(UpdateRegion,((WindowPeek)MyGrafPtr)->updateRgn,((WindowPeek)MyGrafPtr)->updateRgn);
  860.         InvalRgn(UpdateRegion);
  861.         /* get rid of update region */
  862.         DisposeRgn(UpdateRegion);
  863.     }
  864.  
  865.  
  866. /********************************************************************************/
  867. /* utility routines */
  868.  
  869.  
  870. MyBoolean    CWindow::RectVisible(LongPoint Start, LongPoint Extent)
  871.     {
  872.         Rect        Temp;
  873.  
  874.         LongRectToShort(Start,Extent,&Temp);
  875.         return RectInRgn(&Temp,MyGrafPtr->visRgn);
  876.     }
  877.  
  878.  
  879. MyBoolean    CWindow::LongRectToShort(LongPoint Start, LongPoint Extent, Rect* ShortOne)
  880.     {
  881.         register    MyBoolean    Flag;
  882.  
  883.         Start.x += DrawingOrigin.x;
  884.         Start.y += DrawingOrigin.y;
  885.         Extent.x += Start.x;
  886.         Extent.y += Start.y;
  887.         Flag = True;
  888.         if (Start.x < -32767) {Start.x = -32767; Flag = False;}
  889.         if (Start.x > 32767) {Start.x = 32767; Flag = False;}
  890.         if (Extent.x < -32767) {Extent.x = -32767; Flag = False;}
  891.         if (Extent.x > 32767) {Extent.x = 32767; Flag = False;}
  892.         if (Start.y < -32767) {Start.y = -32767; Flag = False;}
  893.         if (Start.y > 32767) {Start.y = 32767; Flag = False;}
  894.         if (Extent.y < -32767) {Extent.y = -32767; Flag = False;}
  895.         if (Extent.y > 32767) {Extent.y = 32767; Flag = False;}
  896.         ShortOne->left = Start.x;
  897.         ShortOne->right = Extent.x;
  898.         ShortOne->top = Start.y;
  899.         ShortOne->bottom = Extent.y;
  900.         return Flag;
  901.     }
  902.  
  903.  
  904. /****************************************************************/
  905. /* Non-window object utility routines */
  906.  
  907.  
  908. Rect            RectOf(short x1, short y1, short x2, short y2)
  909.     {
  910.         Rect    Temp;
  911.  
  912.         Temp.left = x1;
  913.         Temp.top = y1;
  914.         Temp.right = x2;
  915.         Temp.bottom = y2;
  916.         return Temp;
  917.     }
  918.  
  919.  
  920. Point            PointOf(short x, short y)
  921.     {
  922.         Point    Temp;
  923.  
  924.         Temp.v = y;
  925.         Temp.h = x;
  926.         return Temp;
  927.     }
  928.  
  929.  
  930. LongPoint    LongPointOf(long x, long y)
  931.     {
  932.         LongPoint    Temp;
  933.  
  934.         Temp.x = x;
  935.         Temp.y = y;
  936.         return Temp;
  937.     }
  938.  
  939.  
  940. /* get a Rect from the resource file. */
  941. /* high word of RectID = ID of resource */
  942. /* low word of RectID = ID of rect within that resource */
  943. /* the resources are expected to be in big-endian format.  This code */
  944. /* should work even on little-endian processors */
  945. void        GetRect(ulong RectID, LongPoint* Start, LongPoint* Extent)
  946.     {
  947.         Handle        RectRes;
  948.         char*            RectList;
  949.         ulong            Scan;  /* scans the list by byte */
  950.         ushort        Count;
  951.         ushort        IDToFind;
  952.         LongPoint    Temp;
  953.  
  954.         ERROR(ResLoad == 0,PRERR(ForceAbort,"Automatic resource loading is disabled."));
  955.         RectRes = GetResource('∫Rct',(RectID >> 16) & 0x0000ffff);
  956.         if (RectRes == NIL)
  957.             {
  958.                 PRERR(ForceAbort,"GetRect couldn't load resource.");
  959.             }
  960.         ERROR(ResErr != noErr,PRERR(ForceAbort,"Resource Error occurred."));
  961.         HLock(RectRes);
  962.         RectList = *RectRes;  /* dereference */
  963.         IDToFind = 0x0000ffff & RectID;  /* isolate local ID */
  964.         Scan = 2;  /* start with the 2nd word */
  965.         /* getting number of items to do (big-endian) */
  966.         Count = ((uchar*)RectList)[1] + (256 * ((uchar*)RectList)[0]);
  967.         while (Count > 0)
  968.             {
  969.                 if ((((uchar*)RectList)[Scan] * 256) + (((uchar*)RectList)[Scan + 1])
  970.                     == IDToFind)
  971.                     {
  972.                         char*            BaseAddr;
  973.  
  974.                         /* we've found it--copy it out */
  975.                         BaseAddr = (char*)((((StrLen((char*)(RectList + Scan + sizeof(short))))
  976.                             & (~1)) + 2) + (char*)RectList +    Scan + sizeof(short));
  977.                         HUnlock(RectRes);
  978.                         (*Start).x = ((signed char)*(BaseAddr++) * 256) + (uchar)*(BaseAddr++);
  979.                         (*Start).y = ((signed char)*(BaseAddr++) * 256) + (uchar)*(BaseAddr++);
  980.                         (*Extent).x = ((signed char)*(BaseAddr++) * 256) + (uchar)*(BaseAddr++);
  981.                         (*Extent).y = ((signed char)*(BaseAddr++) * 256) + (uchar)*(BaseAddr++);
  982.                         return;
  983.                     }
  984.                 /* skip to next item */
  985.                 Scan +=
  986.                     ((   (StrLen((char*)(RectList + Scan + sizeof(short))))
  987.                     & (~1)) + 2) + sizeof(short) + 4*sizeof(short);
  988.                 Count -= 1;  /* decrement the counter */
  989.             }
  990.         HUnlock(RectRes);
  991.         PRERR(ForceAbort,"GetRect couldn't find rectangle in resource.");
  992.     }
  993.  
  994.  
  995. MyBoolean    LongPtInRect(LongPoint ThePoint, LongPoint Start, LongPoint Extent)
  996.     {
  997.         if (ThePoint.x < Start.x) return False;
  998.         if (ThePoint.x >= Start.x + Extent.x) return False;
  999.         if (ThePoint.y < Start.y) return False;
  1000.         if (ThePoint.y >= Start.y + Extent.y) return False;
  1001.         return True;
  1002.     }
  1003.  
  1004.  
  1005. /* returns new Start */
  1006. LongPoint    CenterRect(LongPoint Extent, LongPoint ContainerExtent)
  1007.     {
  1008.         LongPoint    NewStart;
  1009.  
  1010.         NewStart.x = (ContainerExtent.x - Extent.x) / 2;
  1011.         NewStart.y = (ContainerExtent.y - Extent.y) / 3;
  1012.         if (NewStart.y < 20 + GetMBarHeight())
  1013.             {
  1014.                 NewStart.y = 20 + GetMBarHeight();
  1015.             }
  1016.         return NewStart;
  1017.     }
  1018.  
  1019.  
  1020. LongPoint    AlertCenterRect(LongPoint Extent, LongPoint ContainerExtent)
  1021.     {
  1022.         LongPoint    NewStart;
  1023.  
  1024.         NewStart.x = (ContainerExtent.x - Extent.x) / 2;
  1025.         NewStart.y = (ContainerExtent.y / 3) - Extent.y;
  1026.         if (NewStart.y < 40)
  1027.             {
  1028.                 NewStart.y = 40;
  1029.             }
  1030.         return NewStart;
  1031.     }
  1032.  
  1033.  
  1034. LongPoint    GetLongMouseLoc(void)
  1035.     {
  1036.         Point                MouseLoc;
  1037.         LongPoint        Result;
  1038.  
  1039.         GetMouse(&MouseLoc);
  1040.         LocalToGlobal(&MouseLoc);
  1041.         Result.x = MouseLoc.h;
  1042.         Result.y = MouseLoc.v;
  1043.         return Result;
  1044.     }
  1045.  
  1046.  
  1047. short            GetFontID(PString FontName)
  1048.     {
  1049.         short            FontID;
  1050.  
  1051.         GetFNum(FontName,&FontID);
  1052.         return FontID;
  1053.     }
  1054.  
  1055.  
  1056. void            SectLongRect(LongPoint Start1, LongPoint Extent1, LongPoint Start2,
  1057.                         LongPoint Extent2, register LongPoint* S, register LongPoint* E)
  1058.     {
  1059.         /* normalize the rectangles */
  1060.         if (Extent1.x < 0)
  1061.             {
  1062.                 Start1.x += Extent1.x;
  1063.                 Extent1.x = -Extent1.x;
  1064.             }
  1065.         if (Extent1.y < 0)
  1066.             {
  1067.                 Start1.y += Extent1.y;
  1068.                 Extent1.y = -Extent1.y;
  1069.             }
  1070.         if (Extent2.x < 0)
  1071.             {
  1072.                 Start2.x += Extent2.x;
  1073.                 Extent2.x = -Extent2.x;
  1074.             }
  1075.         if (Extent2.y < 0)
  1076.             {
  1077.                 Start2.y += Extent2.y;
  1078.                 Extent2.y = -Extent2.y;
  1079.             }
  1080.         /* constrain topleft corner */
  1081.         if (Start1.x > Start2.x)
  1082.             {
  1083.                 S->x = Start1.x;
  1084.             }
  1085.          else
  1086.             {
  1087.                 S->x = Start2.x;
  1088.             }
  1089.         if (Start1.y > Start2.y)
  1090.             {
  1091.                 S->y = Start1.y;
  1092.             }
  1093.          else
  1094.             {
  1095.                 S->y = Start2.y;
  1096.             }
  1097.         /* constrain bottomright corner */
  1098.         if (Start1.x+Extent1.x > Start2.x+Extent2.x)
  1099.             {
  1100.                 E->x = (Start2.x+Extent2.x) - S->x;
  1101.             }
  1102.          else
  1103.             {
  1104.                 E->x = (Start1.x+Extent1.x) - S->x;
  1105.             }
  1106.         if (Start1.y+Extent1.y > Start2.y+Extent2.y)
  1107.             {
  1108.                 E->y = (Start2.y+Extent2.y) - S->y;
  1109.             }
  1110.          else
  1111.             {
  1112.                 E->y = (Start1.y+Extent1.y) - S->y;
  1113.             }
  1114.     }
  1115.  
  1116.  
  1117. LongPoint    MainScreenSize(void)
  1118.     {
  1119.         return LongPointOf(screenBits.bounds.right - screenBits.bounds.left,
  1120.             screenBits.bounds.bottom - screenBits.bounds.top);
  1121.     }
  1122.  
  1123.  
  1124. PicHandle    GetPic(short PicID)
  1125.     {
  1126.         PicHandle        Temp;
  1127.  
  1128.         ERROR(ResLoad == 0,PRERR(ForceAbort,"Automatic resource loading is disabled."));
  1129.         Temp = (PicHandle)GetResource('PICT',PicID);
  1130.         ERROR(Temp==NIL,PRERR(ForceAbort,"GetPic: Couldn't find PICT"));
  1131.         ERROR(ResErr != noErr,PRERR(ForceAbort,"Resource Error occurred."));
  1132.         return Temp;
  1133.     }
  1134.